package Test;

import java.util.ArrayList;
import java.util.Scanner;
public class Function {
	Double parseDouble(String s) { // 化为分数的形式
		if (s.indexOf('/') != -1) {
			String[] result = s.split("/");
			return Integer.parseInt(result[0])*1.0/(Integer.parseInt(result[1]));
		} else{
			return Double.parseDouble(s);
		} 
	}

	public String CreateFormula() { // 随机产生式子
		ArrayList<String> list = new ArrayList<>();
		Scanner scanner = new Scanner(System.in);
		int number = (int) (Math.random() * 3 + 2); // 取数字2-4个
		int bracket = (int) (Math.random() * 2); // 0表示不加括号，1表示加括号
		int left = 0, right = 0;
		if (number != 2 && bracket == 1) {
			left = (int) (Math.random() * (number - 1) + 1); // 表示左括号在第几个数前
			if (left == 1) {
				right = ((int) (Math.random() * (number - 2) + left + 1));// 不允许出现类似（1+9+8+5）这种没有意义的括号
				list.add("(");
			} else { // 表示右括号在第几个数后
				right = ((int) (Math.random() * (number - left) + left + 1));
			}
		}
		// System.out.println("left="+left+" right="+right);
		boolean hasSqure = false;
		list.add((int) (Math.random() * 20) + "");
		for (int i = 1; i < number; i++) {
			switch ((int) (Math.random() * 5)) {
			case 0:
				list.add("+");
				break;
			case 1:
				list.add("-");
				break;
			case 2:
				list.add("*");
				break;
			case 3:
				list.add("/");
				break;
			case 4:
				list.add("^2");// 只加平方，3次方，4次方，5次方...对小学生来说太难了
				// list.add("^"+((int)(Math.random()*2+2))+"");//只有2次方和3次方
				i--;
				hasSqure = true;
				break;
			}
			if (hasSqure) {
				hasSqure = false;
				continue;
			}
			if (left != 1 && left == i + 1)
				list.add("(");
			list.add((int) (Math.random() * 20) + "");
			if (right == i + 1)
				list.add(")");
		}
		String string = "";
//		list.add("=");
		for (String a : list) {
			string += a;
		}
		return string;
	}

	public Double Calculator(String formula) {
		Fraction result = null;
		// 在这里写一个根据式子（字符串formula）写出计算结果（Fraction（分数形式））
		// 加油！可以随便加测试的东西（最后删掉就好了）
		Stack<String> sign = new Stack<String>();
		ArrayList<Double> value = new ArrayList<Double>();
		char[] array = formula.toCharArray();// 选取什么样的容器存放String比较合适需要考虑；
		ArrayList<String> numberStr = new ArrayList<String>();
		ArrayList<Double> numberDou = new ArrayList<Double>();
		// System.out.println("1"+array.toString());
		double num = 0.0, res = 0.0;// 考虑到数值可能为两位；
		int i = 0;
		try {
			for (i = 0; i < array.length; i++) {
				for (int k = i; k < array.length && array[k] >= '0' && array[k] <= '9'; k++, i++) {
					String tmpString = array[i] + "";
					numberStr.add(tmpString);// 不能强制转换为double，原本的number为double类型的，因此char型的array不能直接
					// 在前面加double强制转换
				}

				if (numberStr.size() > 0) {// 通过判断存放数值的数组大小间接判断是否为数字；
					num = 0;
					for (String string : numberStr) {
						numberDou.add(Double.parseDouble(string));
					}
					for (int j = numberDou.size() - 1; j >= 0; j--) {
						num += numberDou.get(j) * Math.pow(10, (numberDou.size() - j - 1));// 超出范围的错误，number.get(j)改为j-1
						// System.out.println(num);
					}
					value.add(num);

					numberStr.clear();
					numberDou.clear();
					i--;
				} else {

					if (array[i] == '(') {
						sign.push("(");
					} else if (array[i] == ')') {
						while (sign.peek() != "(") {
							num = Calculate(value, sign.pop(), value.remove(value.size() - 1));
							value.add(num);// (90*(sin90-1)-66)/7
						}
						sign.pop();
					} else if (array[i] == '+' || array[i] == '-' || array[i] == '*' || array[i] == '/'
							|| array[i] == '^') {
						// 加上现有的符号

						// 如果栈非空，且栈顶的运算符优先级比小于等于入栈的运算符优先级，则一直出栈并计算
						while (!sign.empty()) {
							if (compare(array[i] + "", sign.peek()) == 1) {
								break;
							} else {
								num = Calculate(value, sign.pop(), value.remove(value.size() - 1));
								value.add(num);
							}
						}

						sign.push(array[i] + "");
					}
				}

			}

			// 如果栈为非空的话，则继续计算
			while (!sign.empty()) {
				res = Calculate(value, sign.pop(), value.remove(value.size() - 1));
				value.add(res);
			}

			// 如果出来的结果太小了，则直接赋值为0
			res = value.get(0);
			if (Math.abs(res) < 1e-6) {
				// System.out.println(0);
				// ResTextField1.setText(0+"");
				res = 0.0;
			}
//			Function f = new Function();
//			// System.out.println(res);
//			result = f.parseFraction(res + "");
//			//result.outPut();
//			System.out.println(result.getDenominator()+"/"+result.getNumerator());
//			// Calculator();
//			// System.out.println("计算结果："+result);
//			// ///计算结果出来了！！！！！！！
		} catch (Exception e) {
			// System.out.println("表达式异常");
			String s = "Wrong Expression";

		}
		return res;
	}

	private static double Calculate(ArrayList<Double> value, String c, double num) {// 三角函数的计算(包括平方立方根)
		// TODO Auto-generated method stub
		// 如果遇到左括号，则直接返回当前数，例如"(5)"
		if (c.equals("(")) {
			return num;
		} else if (c.equals("^")) {
			return Math.pow(value.remove(value.size() - 1), num);
		} else if (c.equals("+")) {
			return num + value.remove(value.size() - 1);
		} else if (c.equals("-")) {
			return value.remove(value.size() - 1) - num;
		} else if (c.equals("*")) {
			return value.remove(value.size() - 1) * num;
		} else
			return value.remove(value.size() - 1) / num;

	}

	private static int compare(String a, String b) {// 值为1入栈,a为当前，b为栈顶
		// TODO Auto-generated method stub
		if (a.equals(b) || (a.equals("+") && b.equals("-")) || (a.equals("-") && b.equals("+"))
				|| (a.equals("*") && b.equals("/")) || (a.equals("/") && b.equals("*"))) {
			return 0;
		} else if (b.equals("(")) {
			return 1;
		} else if ((a.equals("*") || a.equals("/") && !b.equals("("))) {
			return 1;
		} else if ((a.equals("*") || a.equals("/")) && (b.equals("+") || b.equals("-"))) {
			return 1;
		} else if (a.equals("^") && (b.equals("+") || b.equals("-") || b.equals("*") || b.equals("/"))) {
			return 1;
		} else {
			return 0;
		}
	}

	public int Gcd(int numerator, int denominator) { // 求最大公约数
		return denominator == 0 ? numerator : Gcd(denominator, numerator % denominator);
	}

	public Fraction Reduction(Fraction f) { // 对一个分数进行通分
		int big = Gcd(f.getNumerator(), f.getDenominator());
		f.setNumerator(f.getNumerator() / big);
		f.setDenominator(f.getDenominator() / big);
		return f;
	}

	public boolean FindSame(String string) {

		return false;
	}

}
